//
//  FtpFileManager.m
//  MooreDoll
//
//  Created by Joe on 2014/12/19.
//  Copyright (c) 2014年 Tank. All rights reserved.
//

#import "NetworkManager.h"
#include "libxclient.h"


@implementation NetworkManager
@synthesize managerObjectContext,vcardResultArray,syncResultArray,syncRosterArray,senderJIDArray,senderVcardArray,senderMsgArray,sendArray;


// keep instance function
+(NetworkManager *)sharedInstance
{
    static NetworkManager *networkManager;
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken,
    ^{
        networkManager = [[NetworkManager alloc] init];
        [[NSNotificationCenter defaultCenter] addObserver:networkManager selector:@selector(buildMessageWhenReceiveVCardWithNotificatio:) name:@"buildMessageWhenReciveVCard" object:nil];
        
        networkManager.sendArray = [[NSMutableArray alloc] init];
        
    });
    
    return networkManager;
}


//recive mp3 from ftp
-(void)reciveDataFromFtpWithDictionary:(NSDictionary *)dictionary
{
    if (managerObjectContext == nil)
        managerObjectContext = ((AppDelegate *)[UIApplication sharedApplication].delegate).managedObjectContext;
    
    if (senderJIDArray == nil)
        senderJIDArray  = [[NSMutableArray alloc] init];
    
    if (senderVcardArray ==nil)
        senderVcardArray  = [[NSMutableArray alloc] init];
    
    if (senderMsgArray == nil)
        senderMsgArray = [[NSMutableArray alloc] init];
    
    
    NSString *filePath = [dictionary objectForKey:@"ftp_recv"];
    NSString *sender = [dictionary objectForKey:@"peer"];
    NSString *sid = [dictionary objectForKey:@"sid"];
    filePath = [self adjustAudioPathWithPath:filePath];
    sender = [self jidAdjustWithJID:sender];
    

    //提取該sender的聊天室
    ChatRoom *rooms_result = [self coreDataSearchWithEntityName:@"ChatRoom"
                                                      Predicate:[[NSString alloc] initWithFormat:@"owner == '%@'",sender] SortBy:nil].firstObject;
    
    //If chatRoom doesn't exist, send vcard request to xmpp , when recive vcard , update message.
    if (rooms_result == nil)
    {
        [senderJIDArray addObject:sender];
        [senderMsgArray addObject:dictionary];
        xclient_vcard_get((char *)[sender UTF8String]);
        // message will create in method which name is {-(void)buildMessageWhenReceiveVCardWithNotificatio:(NSNotification *)notification}
        
    }
    else
    {
        //如果sender有聊天室，新增此message
        ChatMessage *chatMessage = [NSEntityDescription insertNewObjectForEntityForName:@"ChatMessage"
                                                                 inManagedObjectContext:managerObjectContext];
        
        chatMessage.audioPath   = filePath;
        chatMessage.fromWho     = sender;
        chatMessage.toWho       = [[NSUserDefaults standardUserDefaults] objectForKey:@"userJID"];
        chatMessage.message     = @"";
        chatMessage.update      = [NSDate date];
        chatMessage.sid         = sid;
        
        
        [rooms_result addChatPlaceObject:chatMessage];
        rooms_result.lastUpdate = chatMessage.update;
        rooms_result.lastMessage = chatMessage.message;
        
        [managerObjectContext save:nil];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"updateMessage" object:nil];
        
    }
    
    
    
}


//收到vcard information，若是message提出的vcard request，則在此方法更新
-(void)buildMessageWhenReceiveVCardWithNotificatio:(NSNotification *)notification
{
    if (senderJIDArray == nil)
        return;
    
    
    NSDictionary *vcard_dic = [notification object];
    
    //取得vcard jid
    NSString     *vcardJID  = [vcard_dic objectForKey:@"vcard_get"];
    vcardJID = [self jidAdjustWithJID:vcardJID];
    
    NSDictionary *messageDic;

    for (NSDictionary *dic in senderMsgArray)
    {
        //對照訊息字典裡的jid是否相符，若有，將字典提出
        NSString *dicJID1 = [dic objectForKey:@"value2"];// for message
        dicJID1 = [self jidAdjustWithJID:dicJID1];
        NSString *dicJID2 = [dic objectForKey:@"peer"];
        dicJID2 = [self jidAdjustWithJID:dicJID2];
        
        if ([vcardJID isEqualToString:dicJID1] || [vcardJID isEqualToString:dicJID2])
        {
            messageDic = dic;
            break;
        }
    }
    
    if (messageDic != nil)
    {
        BOOL messageReceive = NO,
             mp3Receive     = NO;
        for (NSString *key in messageDic)
        {
            if ([key rangeOfString:@"message_recv"].location !=NSNotFound)
            {
                messageReceive = YES;
                break;
            }
            if ([key rangeOfString:@"ftp"].location != NSNotFound)
            {
                mp3Receive = YES;
                break;
            }
            
        }
        
        
        
        if (messageReceive)
        {
            
            
            NSString *messageBody   = [messageDic objectForKey:@"message_recv"];
            NSRange check1          = [messageBody rangeOfString:@"chatMessage:"];
            
            if (check1.location != NSNotFound )
            {
                ChatRoom *chatRoom      = [NSEntityDescription insertNewObjectForEntityForName:@"ChatRoom" inManagedObjectContext:managerObjectContext];
                chatRoom.owner          = vcardJID;
                chatRoom.displayName    = [[vcard_dic objectForKey:@"NICKNAME"]stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
                
                ChatMessage *message    = [NSEntityDescription insertNewObjectForEntityForName:@"ChatMessage" inManagedObjectContext:managerObjectContext];
                message.audioPath       = @"";
                message.fromWho         = vcardJID;
                message.toWho           = [[NSUserDefaults standardUserDefaults]objectForKey:@"userJID"];
                message.message         = [self adjustMessageWithString:[messageDic objectForKey:@"message_recv"] ];
                //message.sid             = @"";
                message.sid             = @"";
                message.update          = [NSDate date];
                
                [chatRoom addChatPlaceObject:message];
                
                chatRoom.lastMessage = message.message;
                chatRoom.lastUpdate = message.update;
                
                [managerObjectContext save:nil];
            }
        }
        else if (mp3Receive)
        {
            ChatRoom *chatRoom = [NSEntityDescription insertNewObjectForEntityForName:@"ChatRoom" inManagedObjectContext:managerObjectContext];
            chatRoom.owner = vcardJID;
            chatRoom.displayName = [[vcard_dic objectForKey:@"NICKNAME"]stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
            
            ChatMessage *message    = [NSEntityDescription insertNewObjectForEntityForName:@"ChatMessage" inManagedObjectContext:managerObjectContext];
            NSString *audioPath     = [messageDic objectForKey:@"ftp_recv"];
            NSRange range           = [audioPath rangeOfString:@"/Documents"];
            audioPath               = [audioPath substringFromIndex:range.location];
            message.audioPath       = audioPath;
            message.fromWho         = vcardJID;
            message.toWho           = [[NSUserDefaults standardUserDefaults]objectForKey:@"userJID"];
            message.message         = @"";
            message.update          = [NSDate date];
            message.sid             = [messageDic objectForKey:@"sid"];
            
            [chatRoom addChatPlaceObject:message];
            
            chatRoom.lastUpdate = message.update;
            chatRoom.lastMessage = message.message;
            
            [managerObjectContext save:nil];
            
        }
        
        
        for (NSString *jid in senderJIDArray)
        {
            if ([jid isEqualToString:vcardJID])
            {
                [senderJIDArray removeObject:jid];
                break;
            }
        }
        //[senderMsgArray removeObject:messageDic];
        for (NSDictionary *dic  in senderMsgArray)
        {
            if (dic == messageDic)
            {
                [senderMsgArray removeObject:dic];
                break;
            }
        }

    }
    [[NSNotificationCenter defaultCenter] postNotificationName:@"updateMessage" object:nil];
    

}


#pragma mark Roster update
/*
 先取得好友名單 ， 建立好友名單陣列，使用 for 迴圈 去要vcard，vcard的接收是單筆的，當資料進來時先去比對有無domain 如果沒有則加上，再將好友名單與收到的vcard做比對，如果 vcard 與 好友名單的jid 相同，則把好友名單的jid去除，並將vcard 令存在一個陣列，一直重複這個動作直到 好友名單歸0表示 結束
 */
//patrick{

-(void)syncRosterWithStatusArray:(NSArray *)friends
{
    
    if (managerObjectContext == nil)
        managerObjectContext = ((AppDelegate *)[UIApplication sharedApplication].delegate).managedObjectContext;
    
    //同步名冊，先建立Array，用來儲存比對來源及結果
    if (syncRosterArray == nil)
        syncRosterArray = [[NSMutableArray alloc] init];
    
    if (syncResultArray == nil)
        syncResultArray = [[NSMutableArray alloc] init];
    
    [syncRosterArray addObjectsFromArray:friends];
    
    
    //處理掉不存在的roster
    NSArray *allRoster = [self coreDataSearchWithEntityName:@"Roster" Predicate:nil SortBy:nil];
    for (Roster *roster in allRoster)
    {
        BOOL mustDelete = YES;
        for (NSString *jidFromXMPP in friends)
        {
            if ([roster.jid isEqualToString:jidFromXMPP])
            {
                mustDelete = NO;
                break;
            }
            
        }
        if (mustDelete)
        {
            NSArray *chatRoom_Array = [self coreDataSearchWithEntityName:@"ChatRoom"
                                                      Predicate:[[NSString alloc] initWithFormat:@"owner == '%@'",roster.jid]
                                                         SortBy:nil];
            for(ChatRoom *chatRoom in chatRoom_Array)
            {
                [managerObjectContext deleteObject:chatRoom];
                [managerObjectContext save:nil];
            }
            
            [managerObjectContext deleteObject:roster];
            [managerObjectContext save:nil];
        }
    }
    
    for (NSString *jid in syncRosterArray)
    {
        //發送vcard請求
        xclient_vcard_get((char *)[jid UTF8String]);
    }
    
}

/*
 取得Roster 表格  ，使用 vcard陣列 與 roster 做迴圈，比對如果是有相同jid 則更新，如果沒有則增加
 */
-(void)syncRosterExcuse:(NSDictionary *)dic_Vcard
{
    NSString *jid = [dic_Vcard objectForKey:@"vcard_get"];
    if ([jid rangeOfString:@"@bbserver-virtualbox"].location==NSNotFound)
        jid = [jid stringByAppendingString:@"@bbserver-virtualbox"];
    
    
    //因為收到message時，roster有可能來不及更新，所以在來不及更新的case中，丟出vcard request取得相關資訊，並且在此更新
    if (senderJIDArray!=nil)
    {
        BOOL isReceiveMsg = NO;
        
        for (NSString *senderJID in senderJIDArray)
        {
            if ([senderJID isEqualToString:jid])
            {
                [[NSNotificationCenter defaultCenter] postNotificationName:@"buildMessageWhenReciveVCard" object:dic_Vcard];
                isReceiveMsg = YES;
                break;
            }
        }
        
        // 若是message更新，則不屬於名冊的更新，便跳出
        if (isReceiveMsg)
            return;
    }
    
    
    //若syncRosterArray存在，表示已在等待同步階段，若有其他同步請求，不予處理
    if (syncRosterArray!= nil)
    {
        //比對roster名單，取得sync需要的資訊
        for (int i = 0; i<syncRosterArray.count ; i++)
        {
            NSString *rosterJID = [syncRosterArray objectAtIndex:i];
            if ([rosterJID isEqualToString:jid])
            {
                //若符合，儲存資訊並跳出迴圈
                [syncResultArray addObject:dic_Vcard];
                [syncRosterArray removeObject:rosterJID];
                break;
            }
        }
        //比對完畢，執行本機同步動作
        if (syncRosterArray.count==0)
        {
            //assign為nil，sync lock解鎖，若有roster event在這之後進來便可再次同步
            syncRosterArray = nil;
            
            //取出本機名冊名單
            NSManagedObjectContext *managedObjectContext = ((AppDelegate *)[UIApplication sharedApplication].delegate).managedObjectContext;
            NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
            NSEntityDescription *entity = [NSEntityDescription entityForName:@"Roster" inManagedObjectContext:managedObjectContext];
            [fetch setEntity:entity];
            
            NSArray *array_myRoster =[managedObjectContext executeFetchRequest:fetch error:nil];
            Roster *addRoster;
            
            //update roster
            for (NSDictionary *dicFromXMPP in syncResultArray)
            {
                
                NSString *jidFromXMPP = [dicFromXMPP objectForKey:@"vcard_get"];
                if ([jidFromXMPP rangeOfString:@"@bbserver-virtualbox"].location == NSNotFound)
                    jidFromXMPP = [jidFromXMPP stringByAppendingString:@"@bbserver-virtualbox"];
                
                BOOL shouldInsert = YES;
                for (Roster *roster in array_myRoster)
                {
                    //如果找到相同jid，update該roster資訊
                    NSString *jidFromLocal = roster.jid;
                    if ([jidFromLocal rangeOfString:@"@bbserver-virtualbox"].location == NSNotFound)
                        jidFromLocal = [jidFromLocal stringByAppendingString:@"@bbserver-virtualbox"];
                    
                    
                    if ([jidFromLocal isEqualToString:jidFromXMPP])
                    {

                        roster.nickeName = [[dicFromXMPP objectForKey:@"NICKNAME"]stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
                        roster.photoPath = [dicFromXMPP objectForKey:@"PHOTO_PATH"]?[dicFromXMPP objectForKey:@"PHOTO_PATH"]:@"";
                        
                        if ([[jidFromXMPP substringWithRange:NSMakeRange(0, 3)] isEqualToString:@"toy"])
                            roster.type = @"toy";
                        else
                            roster.type = @"user";
                        
                        shouldInsert = NO;
                        [managedObjectContext save:nil];
                    }
                }
                
                //若沒有找到符合的jid，表示該筆資訊需要新增
                if (shouldInsert)
                {
                    
                    
                    addRoster = [NSEntityDescription insertNewObjectForEntityForName:@"Roster" inManagedObjectContext:managedObjectContext];
                    addRoster.photoPath = [dicFromXMPP objectForKey:@"PHOTO_PATH"]?[dicFromXMPP objectForKey:@"PHOTO_PATH"]:@"";
                    addRoster.nickeName = [[dicFromXMPP objectForKey:@"NICKNAME"]stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
                    
                    if ([[jidFromXMPP substringWithRange:NSMakeRange(0, 3)]isEqualToString:@"toy"])
                        addRoster.type = @"toy";
                    else
                        addRoster.type = @"user";
                    addRoster.jid = jidFromXMPP;
                    
                    addRoster.jid_noDomain = [[jidFromXMPP componentsSeparatedByString:@"@"]objectAtIndex:0];

                    [managedObjectContext save:nil];
                }
            }// end for loop
            
        
            //更新所有頁面的roster資訊
            [[NSNotificationCenter defaultCenter] postNotificationName:@"RosterSync" object:nil];
            
            
        }
        
    }
    
}


#pragma mark message receive
// recive Message
-(void)reciveMessageFromServerWithDictionary:(NSDictionary *)dictionary
{
    if (managerObjectContext == nil)
        managerObjectContext  = ((AppDelegate *)[UIApplication sharedApplication].delegate).managedObjectContext;
    
    if (senderJIDArray == nil)
        senderJIDArray  = [[NSMutableArray alloc] init];
    
    if (senderVcardArray ==nil)
        senderVcardArray  = [[NSMutableArray alloc] init];
    
    if (senderMsgArray == nil)
        senderMsgArray = [[NSMutableArray alloc] init];
    
    
    //NSData   *stringData    = [dictionary objectForKey:@"message_recv"];
    //NSString *messageString = [[NSString alloc] initWithData:stringData encoding:NSUTF8StringEncoding];
    NSString *messageString = [dictionary objectForKey:@"message_recv"];
    
    NSString *senderJID     = [self jidAdjustWithJID:[dictionary objectForKey:@"value2"]];
    
    ChatRoom *rooms_result  = [self coreDataSearchWithEntityName:@"ChatRoom"
                                                       Predicate:[[NSString alloc] initWithFormat:@"owner == '%@'",senderJID]
                                                          SortBy:nil].firstObject;
    
    if (rooms_result == nil)
    {
        [senderJIDArray addObject:senderJID];
        [senderMsgArray addObject:dictionary];
        
        xclient_vcard_get((char *)[senderJID UTF8String]);
    }
    else
    {
        //choose the content which one is we need.
        NSRange check1          = [messageString rangeOfString:@"chatMessage:"];
        
        if (check1.location == !NSNotFound )
        {
            ChatMessage *message = [NSEntityDescription insertNewObjectForEntityForName:@"ChatMessage" inManagedObjectContext:managerObjectContext];
            //message.sid = @"";
            message.audioPath = @"";
            message.fromWho = senderJID;
            message.toWho = [[NSUserDefaults standardUserDefaults]objectForKey:@"userJID"];
            message.message = [self adjustMessageWithString:messageString ];
            message.update = [NSDate date];
            [rooms_result addChatPlaceObject:message];
            
            rooms_result.lastUpdate = message.update;
            rooms_result.lastMessage = message.message;
            
            [managerObjectContext save:nil];
            
            [[NSNotificationCenter defaultCenter] postNotificationName:@"updateMessage" object:nil];
        }
    }
    
    
}




#pragma mark ftp send sop
//send data or message end , update new message.
-(void)sendDataSuccessWithDictionary:(NSDictionary *)dictionary
{
    if (managerObjectContext == nil)
        managerObjectContext  = ((AppDelegate *)[UIApplication sharedApplication].delegate).managedObjectContext;
    
    
    NSString *audioPath = [self adjustAudioPathWithPath:[dictionary objectForKey:@"ftp_send"]];
    NSString *message = [dictionary objectForKey:@"message_send"];
    
    
    for (NSDictionary *sendDic in sendArray)
    {
        if ([message isEqualToString:[sendDic objectForKey:@"message"]]  ||
            [audioPath rangeOfString:[sendDic objectForKey:@"audioPath"]].location != NSNotFound)
        {
            ChatMessage *chatMessage = [NSEntityDescription insertNewObjectForEntityForName:@"ChatMessage" inManagedObjectContext:managerObjectContext];
            
            chatMessage.sid         = [dictionary objectForKey:@"sid"];
            chatMessage.fromWho     = [sendDic objectForKey:@"fromWho"];
            chatMessage.toWho       = [sendDic objectForKey:@"toWho"];
            chatMessage.update      = [sendDic objectForKey:@"update"];
            chatMessage.message     = [self adjustMessageWithString:[sendDic objectForKey:@"message"]]?
            [self adjustMessageWithString:[sendDic objectForKey:@"message"]]:
            @"";
            chatMessage.audioPath   = [sendDic objectForKey:@"audioPath"];
            
            [(ChatRoom *)[sendDic objectForKey:@"chatRoom"] addChatPlaceObject:chatMessage];
            ((ChatRoom *)[sendDic objectForKey:@"chatRoom"]).lastUpdate  = chatMessage.update;
            ((ChatRoom *)[sendDic objectForKey:@"chatRoom"]).lastMessage = chatMessage.message;
            [managerObjectContext save:nil];
            
            [sendArray removeObject:sendDic];
            break;
        }
    }
    
    [[NSNotificationCenter defaultCenter] postNotificationName:@"updateMessage" object:nil];
    
}

// send progress
-(void)sendFileProgressWithDictionary:(NSDictionary *)dictionary
{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"sendFileProgress" object:dictionary];
}

-(void)sendFileEndWithDictionary:(NSDictionary *)dictionary
{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"updateMessage" object:nil];
}


#pragma mark ftp receive sop

-(void)receiveFileProgressWithDictionary:(NSDictionary *)dictionary
{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"receiveFileProgress" object:dictionary];
}

-(void)receiveFileEndWithDictionary:(NSDictionary *)dictionary
{
    NSArray *messageArray = [self coreDataSearchWithEntityName:@"ChatMessage"
                                                     Predicate:[[NSString alloc] initWithFormat:@"sid == %@",[dictionary objectForKey:@"sid"]]
                                                        SortBy:nil];
    ChatMessage *chatMessage = messageArray.firstObject;
    NSString *audioPath = [dictionary objectForKey:@"path"];
    audioPath = [self adjustAudioPathWithPath:audioPath];
    
    chatMessage.audioPath = audioPath;
    [managerObjectContext save:nil];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"updateMessage" object:nil];
}


#pragma mark method
-(NSString *)adjustMessageWithString:(NSString *)message
{
    NSString *adjustMessage = message;
    NSRange messageReference = [adjustMessage rangeOfString:@"chatMessage:"];
    if (messageReference.location != NSNotFound)
        adjustMessage = [adjustMessage substringFromIndex:messageReference.location + messageReference.length];
    return adjustMessage;
    
}

-(NSString *)adjustAudioPathWithPath:(NSString *)audioPath
{
    NSString *adjustPath = audioPath;
    
    if ([adjustPath rangeOfString:@"/Documents"].location != NSNotFound)
        adjustPath = [adjustPath substringFromIndex:[adjustPath rangeOfString:@"/Documents"].location];
    
    return adjustPath;
}

-(NSString *)jidAdjustWithJID:(NSString *)jid
{
    NSString *adjustJID = jid;
    
    if ([adjustJID rangeOfString:@"/"].location != NSNotFound)
        adjustJID = [adjustJID substringToIndex:[adjustJID rangeOfString:@"/"].location];
    
    if ([adjustJID rangeOfString:@"@bbserver-virtualbox"].location == NSNotFound)
        adjustJID = [adjustJID stringByAppendingString:@"@bbserver-virtualbox"];
    
    return adjustJID;
}

/*
 取得coreData的資訊
 */
-(NSArray *)coreDataSearchWithEntityName:(NSString *)entityName Predicate:(NSString *)predicateString SortBy:(NSString *)sortString
{
    if (managerObjectContext == nil)
        managerObjectContext  = ((AppDelegate *)[UIApplication sharedApplication].delegate).managedObjectContext;
    
    NSPredicate *predicate;
    NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:managerObjectContext];
    
    [fetch setEntity:entity];
    
    if (predicateString != nil)
    {
        predicate = [NSPredicate predicateWithFormat:predicateString];
        [fetch setPredicate:predicate];
    }
    NSArray *resultArray = [managerObjectContext executeFetchRequest:fetch error:nil];
    return resultArray;
    
}

@end
